#ifndef _csArray_h_
#define _csArray_h_

/********************************************************************
	created:	2009/11/06
	created:	6:11:2009   14:25
	filename: 	e:\csEngine\csCoreLib\src\util\csArray.h
	file path:	e:\csEngine\csCoreLib\src\util
	file base:	csArray
	file ext:	h
	author:		dongchengok
	
	purpose:	template array
*********************************************************************/
#include "csType.h"
//------------------------------------------------------------------------
template<typename T, bool NeedConstruct=true, bool NeedDestruct=true, s32 alignment=csALIGNMENT_DEFAULT>
class csArray
{
public:
	typedef T*			iterator;
	typedef const T*	const_iterator;
public:
	csArray();
	csArray(const csArray<T,NeedConstruct,NeedDestruct,alignment>& rhs);
	csArray(s32 capacity);
	csArray(s32 size, const T& fillValue);
	csArray(s32 size, const T& fillValue, s32 capacity);
	~csArray();

	//void				assign(s32 count, const T& val);

	T&					operator[](s32 idx);
	const T&			operator[](s32 idx) const;
	void				operator =(const csArray<T,NeedConstruct,NeedDestruct,alignment>& rhs);
	bool				operator==(const csArray<T,NeedConstruct,NeedDestruct,alignment>& rhs) const;
	bool				operator!=(const csArray<T,NeedConstruct,NeedDestruct,alignment>& rhs) const;

	T&					at(s32 idx);
	s32					size() const;
	void				resize(s32 size);
	void				resize(s32 size, const T& val);
	s32					capacity() const;
	s32					get_reserve() const;
	void				reserve(s32 size);

	//fast swap two array
	void				swap(csArray<T,NeedConstruct,NeedDestruct,alignment>& rhs);

	void				push_back(const T& rhs);
	void				pop_back();

	bool				empty() const;
	//set size to zero, destruct the element, but the capacity does not change
	void				clear();
	//make the capacity==size
	void				trim();
	iterator			find(const T& val);
	const_iterator		find(const T& val) const;

	//preformance fuck
	//insert before the idx element
	void				insert(s32 idx, const T& ele);
	void				insert(iterator it, const T& ele);
	void				insert(s32 idx, const T& ele, s32 num);
	void				insert(iterator it, const T& ele, s32 num);
	void				erase(s32 idx, s32 num=1);
	void				erase(iterator where);
	void				erase(iterator beginIt, iterator endIt);


	iterator			begin();
	const_iterator		begin() const;
	iterator			end();
	const_iterator		end() const;

	T&					front();
	const T&			front() const;
	T&					back();
	const T&			back() const;

	void				to_array(T** outArray) const;

protected:
	void				_set_capacity(s32 capacity);
	void				_copy(const csArray<T,NeedConstruct,NeedDestruct,alignment>& rhs);
	void				_cleanup();
	void				_realloc(s32 capacity);
	void				_grow();
	void				_move(s32 from, s32 to);

	
protected:
	s32					m_size;
	s32					m_capacity;
	T*					m_pData;
};

template<typename T>
class csPointerArray : public csArray<T,false,false,32>{};
template<typename T>
class csStructArray : public csArray<T,false,false,32>{};

#include "csArray.inl"
#endif // _csArray_h_